#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>
#include<unistd.h>
#include <stdio.h>
#include <sys/epoll.h>

#include <vector>
#include <memory>

using namespace std;

class Channel
{
    public:

    Channel(int _fd,int _event)
    {
    fd=_fd;
    event=_event;
    
    }

    void handleEvent()
    {
      if(event&(EPOLLIN|EPOLLPRI|EPOLLRDHUP))
      {
      printf("read\n");
      }
     else if(event&EPOLLOUT)
      {
      printf("write\n");
      }
     else 
{
 printf("otherevent\n");
}
    }
  int fd;
  int event;



};

class Poller
{
    public:
       Poller()
        {
            _epollfd=epoll_create(256);
        }
    void   epoll_add_(shared_ptr<Channel> para)
        {
            struct  epoll_event ev;
            ev.data.fd=para->fd;
            ev.events=para->event;
           
            sp_all_channel[para->fd]=para;

	    	
            if(epoll_ctl(_epollfd,EPOLL_CTL_ADD,para->fd,&ev )<0)
		{ 
printf("error\n");
}
        }

  
    
    std::vector<shared_ptr<Channel>>  pollrun()
    {
        vector<shared_ptr<Channel>>  vec;
        struct  epoll_event events[128];
        int calledfd=epoll_wait(_epollfd,events,20,50);
        for(int i=0;i<calledfd;i++)
        {
         printf("eventhappen\n"); 
          int fd=events[i].data.fd;
          shared_ptr<Channel> currChannel=sp_all_channel[fd];
          currChannel->event=events[i].events;
          vec.push_back(currChannel);
          
        
        }
       return vec;
    }

int _epollfd;
static const int MAXFDS = 100000;
shared_ptr<Channel>  sp_all_channel[MAXFDS];

};

class Loop

{
    public:
    Loop(): _poll(new Poller)
    {
    }
    void AddChannel(shared_ptr<Channel> para)
    {
       (*_poll).epoll_add_(para);
    }
   void myloop()
   {
printf("beginloop\n");
       while(true)
       {
   vector<shared_ptr<Channel>>  rlt= _poll->pollrun(); //thin not use auto
for(auto ele:rlt)
   {
    ele->handleEvent();
   
   }
       }

   }
shared_ptr<Poller> _poll; 


};



int CreateListenFd(int port)
{

printf("createfd\n");
int on = 1;
     int    _listenfd = socket(AF_INET, SOCK_STREAM, 0);
     struct sockaddr_in servaddr;
     fcntl(_listenfd, F_SETFL, O_NONBLOCK); //no-block io 
     setsockopt(_listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
     servaddr.sin_family = AF_INET;
     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
     servaddr.sin_port = htons(port);
 
     bind(_listenfd,(const struct sockaddr*)&servaddr,sizeof(servaddr));
     
     listen(_listenfd, 10);

     return _listenfd;
}

int main()

{
Loop myrunloop;
for(int i=0;i<5;i++)
{
int  fd=CreateListenFd(i+9000);
 shared_ptr<Channel>  ch=make_shared<Channel>(fd,EPOLLIN|EPOLLET); //fd event
 
myrunloop.AddChannel(ch);
}

myrunloop.myloop();

return 0;
}





